home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
011
/
fastbios.arc
/
BREAKON.ASM
next >
Wrap
Assembly Source File
|
1985-12-24
|
8KB
|
237 lines
title BREAKON
comment \
Function Ctrl-Brk terminates any program
Author Robert Wagner
Date Written 12/22/85
Remarks Must the the last program in your AUTOEXEC.BAT
When Ctrl-Brk is hit, does the following:
..makes sure you are not on the command line or
in a resident program or executing a DOS call
(a second Ctrl-Brk will bypass these checks).
..resets the keyboard
..discards all interrupts pending in the 8259
..resets 8255 and 8259 ports (61 and 21)
..does a BIOS break (1B) and a DOS break (23) to
give your program's Ctrl-Brk routine a chance to do
its thing.
If I do not get control back, third Ctrl-Brk will
bypass this step.
..restores all interrupt vectors to the values
they had when I was made resident. That's
why I have to be last in the AUTOEXEC.
..restores screen parameters in BIOS segment
..clears the screen (into BACKSCRL, if present)
..does not flush keyboard buffer. May help to
indicate where it blew up.
..does a terminate (4C) with return code FF.
\
cseg segment
assume cs:cseg,ds:cseg,es:nothing
org 100H ; I am .COM
start proc far
jmp makeres
start endp
db 'BREAKON v1.1 Public Domain 1985 Robert Wagner, 806-763-3375'
a_int09 dd 0 ; original INT 09
a_int21 dd 0 ; original INT 21
zero dd 0 ; addr of interrupt vectors
port21 db 0 ; initial values in ports
port61 db 0
in_prog db 0 ; in-progress flag
a_break dw 71H,40H ; addr of BIOS break bit
a_bios dw 49H,40H ; addr of BIOS screen stuff
BIOSwss db 30 dup(?) ; save area for above
DOSregs dw 6 dup(?) ; save area for registers of last dos call
ctrl_key equ 29
scroll_key equ 70
s_vector equ 512
assume cs:cseg,ds:nothing,es:nothing
int09 proc far ; comes here on keystroke
sti
push ax
in al,60H ; read the keycode
test al,10000000B ; ignore "key break"
jnz int09x
cmp al,ctrl_key ; ignore Ctrl key
je int09x
cmp al,scroll_key ; check for Brk
je int09a
mov cs:in_prog,0 ; some other key, reset in progress flag
int09x: pop ax
jmp dword ptr cs:a_int09 ; jump to original int09
int09a: mov ah,2 ; check for Ctrl-Brk
int 16H
test al,00000100B
jz int09x
call bomb ; do it
jmp int09x
int09 endp
assume cs:cseg,ds:cseg,es:nothing
bomb proc near
push ds
push es
push bx
mov ax,cs
mov ds,ax
inc in_prog
cmp in_prog,3 ; third try?
je bombc ; y - bypass below tests, do it
cmp in_prog,2 ; second try?
je bomba ; y - bypass some of the tests
mov bx,sp
mov ax,word ptr ss:[bx+12] ; get segment of interrupted task
mov bx,cs
cmp ax,bx ; compare to mine
jb bombx ; lower: resident pgm or DOS, exit
cmp ax,0F000H ; BIOS call in progress?
jae bombx ; y - exit
bomba: mov ax,5100H ; get psp of current task
int 21H
mov es,bx
cmp byte ptr es:[0],0CDH ; look like a program?
jne bombx
mov ax,es
cmp ax,es:[16H] ; was it invoked by itself?
jne bombc ; y - it's COMMAND.COM
mov in_prog,0 ; get out
bombx: pop bx
pop es
pop ds
ret
bombc: cld
in al,61H ; reset the keyboard (via 8255)
or al,10000000B
out 61H,al
mov al,port61 ; reset the 8255
and al,01111111B
out 61H,al
cli
mov al,port21 ; reset interrupts enabled (port 21)
out 21H,al
mov cx,8
bomb1: mov al,20H ; cancel anything stacked in 8259
out 20H,al
loop bomb1
sti
cmp in_prog,3
je bomb2
les di,dword ptr a_break
mov al,80H
stosb ; set bios break bit
int 1BH ; do an int1B (BIOS break function)
mov ax,dosregs+00 ; load the registers from last int21
mov bx,dosregs+02
mov cx,dosregs+04
mov dx,dosregs+06
mov es,dosregs+08
mov ds,dosregs+10
int 23H ; do an int23 (DOS break function)
bomb2: mov ax,cs
mov ds,ax
cld
cli
les di,zero ; restore interrupt vectors
lea si,intvec
mov cx,s_vector
rep movsw
les di,dword ptr a_bios ; restore screen stuff
lea si,BIOSwss
mov cx,size BIOSwss
rep movsb
les di,dword ptr a_break
mov al,0
stosb ; clear bios break bit
sti
mov al,0 ; clear the screen
mov cx,0
mov dx,(24*256)+79
mov bh,7
mov ah,6
int 10H
mov dx,0 ; cursor home
mov bh,0
mov ah,2
int 10H
mov in_prog,0
mov ah,4CH ; end the process
mov al,0FFH
int 21H
bomb endp
int21 proc far ; comes here on int21
assume cs:cseg,ds:nothing,es:nothing
cmp cs:in_prog,0
jne int21x
mov cs:dosregs+00,ax ; save the registers
mov cs:dosregs+02,bx
mov cs:dosregs+04,cx
mov cs:dosregs+06,dx
mov cs:dosregs+08,es
mov cs:dosregs+10,ds
int21x: jmp dword ptr cs:a_int21
int21 endp
makeres proc near
assume cs:cseg,ds:cseg,es:nothing
mov ax,3509H ; get vector 09H
int 21H
mov word ptr a_int09,bx
mov word ptr a_int09+2,es
mov ax,2509H ; set vector 09H
mov dx,offset int09
int 21H
mov ax,3521H ; get vector 21H
int 21H
mov word ptr a_int21,bx
mov word ptr a_int21+2,es
mov ax,2521H ; set vector 21H
mov dx,offset int21
int 21H
in al,21H ; save port 21
mov port21,al
in al,61H ; save port 61
mov port61,al
mov ax,ds
mov es,ax
lds si,dword ptr cs:a_bios ; save screen stuff
lea di,BIOSwss
mov cx,size BIOSwss
rep movsb
lds si,cs:zero ; save interrupt vectors
lea di,intvec
mov cx,s_vector
rep movsw
mov ax,3100H ; ---- terminate and stay resident ----
mov dx,offset intvec+s_vector+s_vector
mov cl,4
shr dx,cl ; should be able to write (the_end/16+1)
inc dx
int 21H
makeres endp
intvec label word ; stores original int vectors here
cseg ends
end start